﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using T.FAS.Runtime.Metadata.Entity.DataModel;

namespace T.FAS.Runtime.Metadata.Entity.DataModel
{
    /// <summary>
    /// 领域对象
    /// </summary>
    [Serializable]
    public class CompositeNodeObject : System.ICloneable
    {

        /// <summary>
        /// ID
        /// </summary>
        public string ID { get; set; }

        /// <summary>
        /// 名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 是否为根结点对象
        /// </summary>
        public bool IsRootObject { get; set; }

        /// <summary>
        /// 隶属的领域模型ID
        /// </summary>
        public string CompositeDataObjectID { get; set; }

        /// <summary>
        /// 父级领域对象ID
        /// </summary>
        public string ParentObjectID { get; set; }

        /// <summary>
        /// 属性名称
        /// </summary>
        public string PropertyName { get; set; }

        ///// <summary>
        ///// 类名称
        ///// </summary>
        //public string Clazz { get; set; }

        /// <summary>
        /// 类反射信息
        /// </summary>
        public string ClazzReflectType { get; set; }

        /// <summary>
        /// 数据对象ID
        /// </summary>
        public string DataObjectID { get; set; }

        /// <summary>
        /// 数据对象对应物理表的表名
        /// </summary>
        public string DataObjectTableAlias { get; set; }

        /// <summary>
        /// 是否懒加载
        /// </summary>
        public bool IsLazyLoad { get; set; }

        /// <summary>
        /// 创建人
        /// </summary>
        //[DataMember]
        [JsonIgnore]
        public string Creator { get; set; }

        /// <summary>
        /// 创建时间
        /// </summary>        
        //[DataMember]
        [JsonIgnore]
        public DateTime CreateTime { get; set; }

        /// <summary>
        /// 最后修改人
        /// </summary>
        //[DataMember]
        [JsonIgnore]
        public string LastModifier { get; set; }

        /// <summary>
        /// 最后修改时间
        /// </summary>        
        //[DataMember]
        [JsonIgnore]
        public DateTime LastModifyTime { get; set; }

        [NonSerialized]
        [JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Ignore)]
        private CompositeDataObject compositeDataObject;

        /// <summary>
        /// 隶属的领域模型，json序列化忽略，在CDO中重新构建引用
        /// </summary>                
        [JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Ignore)]
        [JsonIgnore]
        public CompositeDataObject CompositeDataObject
        {
            get
            {
                return compositeDataObject;
            }
            set
            {
                compositeDataObject = value;
                if (value != null)
                    CompositeDataObjectID = value.ID;
            }
        }

        [NonSerialized]
        [JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Ignore)]
        [JsonIgnore]
        private CompositeNodeObject parentObject;

        /// <summary>
        /// 父级领域对象，json序列化忽略，在CDO中重新构建引用
        /// </summary>        
        [JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Ignore)]
        [JsonIgnore]
        public CompositeNodeObject ParentObject
        {
            get
            {
                return parentObject;
            }
            set
            {
                parentObject = value;
                if (value != null)
                    ParentObjectID = value.ID;
            }
        }

        //子领域对象集合
        private List<CompositeNodeObject> childCompositeNodeObjects;

        /// <summary>
        /// 子领域对象集合，json序列化忽略，在CDO中重新构建引用，（日志中Debug的json会丢失层级结构）
        /// </summary>
        [JsonIgnore]
        [JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Ignore)]
        public virtual List<CompositeNodeObject> ChildCompositeNodeObjects
        {
            get
            {
                if (childCompositeNodeObjects == null)
                    childCompositeNodeObjects = new List<CompositeNodeObject>();

                return childCompositeNodeObjects;
            }
            set
            {
                childCompositeNodeObjects = value;
            }
        }

        //元素集合
        private List<CompositeNodeObjectElement> elements;

        /// <summary>
        /// 元素集合看，json序列化保留
        /// </summary>
        public List<CompositeNodeObjectElement> Elements
        {
            get
            {
                if (elements == null)
                    elements = new List<CompositeNodeObjectElement>();

                return elements;
            }
            set
            {
                elements = value;
            }
        }

        //[NonSerialized]
        private DataObject dataObject;

        /// <summary>
        /// 关联的数据对象，json序列化保留
        /// </summary>
        public DataObject DataObject
        {
            get
            {
                return dataObject;
            }
            set
            {
                dataObject = value;
            }
        }

        private List<Association> associations;

        /// <summary>
        /// 关联，json序列化保留
        /// </summary>
        public List<Association> Associations
        {
            get
            {
                if (associations == null)
                    associations = new List<Association>();

                return associations;
            }
            set
            {
                associations = value;
            }
        }


        /*******************CompositeNodeObject方法*******************/

        /// <summary>
        /// 构造函数
        /// </summary>
        public CompositeNodeObject()
        {
            ID = Guid.NewGuid().ToString();
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="dataObject"></param>
        public CompositeNodeObject(DataObject dataObject) : this()
        {
            this.Name = dataObject.Name;
            this.DataObject = dataObject;
            dataObject.Columns.ForEach(i =>
            {
                var element = new CompositeNodeObjectElement()
                {
                    ID = Guid.NewGuid().ToString(),
                    Alias = i.ColumnName,
                    Creator = dataObject.Creator,
                    CreateTime = DateTime.Now,
                    LastModifier = dataObject.LastModifier,
                    LastModifyTime = DateTime.Now,
                    DataColumnID = i.ID,
                    DisplayName = i.DisplayName,
                    CompositeNodeObjectID = this.ID,
                    IsAllowNull = i.IsNullable,
                    Length = i.Length,
                    Precision = i.Precision,
                    Name = i.ColumnName,
                    ElementType = ElementType.Normal,
                    /***********低代码改动：将DO.Column的应用程序类型映射到CNO.Element的数据类型************/
                    DataType = ElementDataTypeUtils.ConvertToElementDataType(i.ApplicationDataType)
                };
                this.Elements.Add(element);
            });
            this.DataObjectID = dataObject.ID;
        }

        public object Clone()
        {
            return this.MemberwiseClone();
        }
    }
}
